home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / usenet / volume11 / larn / part07 < prev    next >
Encoding:
Internet Message Format  |  1991-01-03  |  53.6 KB

  1. Path: uunet!zephyr.ens.tek.com!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v11i090:  larn - dungeon type adventure game, Part07/11
  5. Message-ID: <6721@tekred.CNA.TEK.COM>
  6. Date: 18 Dec 90 18:34:26 GMT
  7. Sender: news@tekred.CNA.TEK.COM
  8. Lines: 1965
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: routley@tle.ENET.DEC.COM (Kevin Routley)
  12. Posting-number: Volume 11, Issue 90
  13. Archive-name: larn/Part07
  14. Environment: Unix, VMS, MS-DOS, termcap
  15.  
  16.  
  17.  
  18. #! /bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 7 (of 11)."
  25. # Contents:  bill.c global.c io.c
  26. # Wrapped by billr@saab on Tue Dec 18 10:14:20 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'bill.c' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'bill.c'\"
  30. else
  31. echo shar: Extracting \"'bill.c'\" \(7074 characters\)
  32. sed "s/^X//" >'bill.c' <<'END_OF_FILE'
  33. X#include "header.h"
  34. X/* bill.c         "Larn is copyrighted 1986 by Noah Morgan. */
  35. X
  36. X# ifdef MAIL
  37. X# ifdef VMS
  38. X# define MAILTMP    "sys$scratch:"
  39. X# else
  40. X# define MAILTMP    "/tmp/#"
  41. X# endif
  42. Xstatic int pid;
  43. Xstatic char mail600[sizeof(MAILTMP)+sizeof("mail600")+20];
  44. X# endif
  45. X/*
  46. X *    function to create the tax bill for the user
  47. X */
  48. X# ifdef MAIL
  49. Xstatic letter1()
  50. X# else
  51. Xstatic letter1(gold)
  52. Xlong gold;
  53. X# endif
  54. X  {
  55. X# ifdef MAIL
  56. X  sprintf(mail600,"%s%dmail600",MAILTMP,pid); /* prepare path */
  57. X  if (lcreat(mail600) < 0) { write(1,"can't write 600 letter\n",23); return(0);}
  58. X  lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
  59. X# endif
  60. X  standout("From:"); lprcat("  the LRS (Larn Revenue Service)\n");
  61. X  standout("\nSubject:"); lprcat("  undeclared income\n");
  62. X  lprcat("\n   We heard you survived the caverns of Larn.  Let me be the");
  63. X  lprcat("\nfirst to congratulate you on your success.  It is quite a feat.");
  64. X  lprcat("\nIt must also have been very profitable for you.");
  65. X  lprcat("\n\n   The Dungeon Master has informed us that you brought");
  66. X# ifdef MAIL
  67. X  lprintf("\n%d gold pieces back with you from your journey.  As the",(long)c[GOLD]);
  68. X# else
  69. X  lprintf("\n%d gold pieces back with you from your journey.  As the", gold);
  70. X# endif
  71. X  lprcat("\ncounty of Larn is in dire need of funds, we have spared no time");
  72. X  lprintf("\nin preparing your tax bill.  You owe %d gold pieces as",
  73. X# ifdef MAIL
  74. X    (long)c[GOLD]*TAXRATE);
  75. X# else
  76. X    gold * TAXRATE);
  77. X# endif
  78. X  lprcat("\nof this notice, and is due within 5 days.  Failure to pay will");
  79. X  lprcat("\nmean penalties.  Once again, congratulations, We look forward");
  80. X  lprcat("\nto your future successful expeditions.\n");
  81. X# ifdef MAIL
  82. X  lwclose();
  83. X# endif
  84. X  return(1);
  85. X  }
  86. X
  87. Xstatic letter2()
  88. X  {
  89. X# ifdef MAIL
  90. X  sprintf(mail600,"%s%dmail600",MAILTMP,pid); /* prepare path */
  91. X  if (lcreat(mail600) < 0) { write(1,"can't write 601 letter\n",23); return(0);}
  92. X  lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
  93. X# endif
  94. X  standout("From:"); lprcat("  His Majesty King Wilfred of Larndom\n");
  95. X  standout("\nSubject:"); lprcat("  a noble deed\n");
  96. X  lprcat("\n   I have heard of your magnificent feat, and I, King Wilfred,");
  97. X  lprcat("\nforthwith declare today to be a national holiday.  Furthermore,");
  98. X  lprcat("\nhence three days, Ye be invited to the castle to receive the");
  99. X  lprcat("\nhonour of Knight of the realm.  Upon thy name shall it be written. . .");
  100. X  lprcat("\nBravery and courage be yours.");
  101. X  lprcat("\nMay you live in happiness forevermore . . .\n");
  102. X# ifdef MAIL
  103. X  lwclose();
  104. X# endif
  105. X  return(1);
  106. X  }
  107. X
  108. Xstatic letter3()
  109. X  {
  110. X# ifdef MAIL
  111. X  sprintf(mail600,"%s%dmail600",MAILTMP,pid); /* prepare path */
  112. X  if (lcreat(mail600) < 0) { write(1,"can't write 602 letter\n",23); return(0);}
  113. X  lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
  114. X# endif
  115. X  standout("From:"); lprcat("  Count Endelford\n");
  116. X  standout("\nSubject:"); lprcat("  You Bastard!\n");
  117. X  lprcat("\n   I heard (from sources) of your journey.  Congratulations!");
  118. X  lprcat("\nYou Bastard!  With several attempts I have yet to endure the");
  119. X  lprcat(" caves,\nand you, a nobody, makes the journey!  From this time");
  120. X  lprcat(" onward, bewarned\nupon our meeting you shall pay the price!\n");
  121. X# ifdef MAIL
  122. X  lwclose();
  123. X# endif
  124. X  return(1);
  125. X  }
  126. X
  127. Xstatic letter4()
  128. X  {
  129. X# ifdef MAIL
  130. X  sprintf(mail600,"%s%dmail600", MAILTMP,pid); /* prepare path */
  131. X  if (lcreat(mail600) < 0) { write(1,"can't write 603 letter\n",23); return(0);}
  132. X  lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
  133. X# endif
  134. X  standout("From:"); lprcat("  Mainair, Duke of Larnty\n");
  135. X  standout("\nSubject:"); lprcat("  High Praise\n");
  136. X  lprcat("\n   With a certainty a hero I declare to be amongst us!  A nod of");
  137. X  lprcat("\nfavour I send to thee.  Me thinks Count Endelford this day of");
  138. X  lprcat("\nright breath'eth fire as of dragon of whom ye are slayer.  I");
  139. X  lprcat("\nyearn to behold his anger and jealously.  Should ye choose to");
  140. X  lprcat("\nunleash some of thy wealth upon those who be unfortunate, I,");
  141. X  lprcat("\nDuke Mainair, Shall equal thy gift also.\n");
  142. X# ifdef MAIL
  143. X  lwclose();
  144. X# endif
  145. X  return(1);
  146. X  }
  147. X
  148. Xstatic letter5()
  149. X  {
  150. X# ifdef MAIL
  151. X  sprintf(mail600,"%s%dmail600", MAILTMP,pid); /* prepare path */
  152. X  if (lcreat(mail600) < 0) { write(1,"can't write 604 letter\n",23); return(0);}
  153. X  lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
  154. X# endif
  155. X  standout("From:"); lprcat("  St. Mary's Children's Home\n");
  156. X  standout("\nSubject:"); lprcat("  these poor children\n");
  157. X  lprcat("\n   News of your great conquests has spread to all of Larndom.");
  158. X  lprcat("\nMight I have a moment of a great man's time.  We here at St.");
  159. X  lprcat("\nMary's Children's Home are very poor, and many children are");
  160. X  lprcat("\nstarving.  Disease is widespread and very often fatal without");
  161. X  lprcat("\ngood food.  Could you possibly find it in your heart to help us");
  162. X  lprcat("\nin our plight?  Whatever you could give will help much.");
  163. X  lprcat("\n(your gift is tax deductible)\n");
  164. X# ifdef MAIL
  165. X  lwclose();
  166. X# endif
  167. X  return(1);
  168. X  }
  169. X
  170. Xstatic letter6()
  171. X  {
  172. X# ifdef MAIL
  173. X  sprintf(mail600, "%s%dmail600", MAILTMP, pid); /* prepare path */
  174. X  if (lcreat(mail600) < 0) { write(1,"can't write 605 letter\n",23); return(0);}
  175. X  lprcat("\n\n\n\n\n\n\n\n\n\n\n\n");
  176. X# endif
  177. X  standout("From:"); lprcat("  The National Cancer Society of Larn\n");
  178. X  standout("\nSubject:"); lprcat("  hope\n");
  179. X  lprcat("\nCongratulations on your successful expedition.  We are sure much");
  180. X  lprcat("\ncourage and determination were needed on your quest.  There are");
  181. X  lprcat("\nmany though, that could never hope to undertake such a journey");
  182. X  lprcat("\ndue to an enfeebling disease -- cancer.  We at the National");
  183. X  lprcat("\nCancer Society of Larn wish to appeal to your philanthropy in");
  184. X  lprcat("\norder to save many good people -- possibly even yourself a few");
  185. X  lprcat("\nyears from now.  Much work needs to be done in researching this");
  186. X  lprcat("\ndreaded disease, and you can help today.  Could you please see it");
  187. X  lprcat("\nin your heart to give generously?  Your continued good health");
  188. X  lprcat("\ncan be your everlasting reward.\n");
  189. X# ifdef MAIL
  190. X  lwclose();
  191. X# endif
  192. X  return(1);
  193. X  }
  194. X
  195. X
  196. Xstatic int (*pfn[])()= { letter1, letter2, letter3, letter4, letter5, letter6 };
  197. X
  198. X# ifdef MAIL
  199. X/*
  200. X *    function to mail the letters to the player if a winner
  201. X */
  202. Xmailbill()
  203. X    {
  204. X#ifdef VMS
  205. X    register int i;
  206. X    char buf[128];
  207. X    pid = getpid();
  208. X    for (i=0; i<sizeof(pfn)/sizeof(int (*)()); i++)
  209. X        if ((*pfn[i])()) {
  210. X            sprintf(buf, "mail %s %s\n", loginname, mail600);
  211. X            oneliner(buf);
  212. X            delete(mail600);
  213. X        }
  214. X    }
  215. X#else
  216. X    register int i;
  217. X    char buf[128];
  218. X    wait(0);  pid=getpid();
  219. X    if (fork() == 0)
  220. X        {
  221. X        resetscroll();
  222. X        for (i=0; i<sizeof(pfn)/sizeof(int (*)()); i++)
  223. X            if ((*pfn[i])())
  224. X                {
  225. X                sleep(20);
  226. X                sprintf(buf,"mail %s < %s",loginname,mail600);
  227. X                system(buf);  unlink(mail600);
  228. X                }
  229. X        exit();
  230. X        }
  231. X    }
  232. X#endif
  233. X# else
  234. X
  235. X/* Page the mail to the terminal    - dgk
  236. X */
  237. Xreadmail(gold)
  238. Xlong    gold;
  239. X{
  240. X    register int i;
  241. X
  242. X    for (i = 0; i < (sizeof pfn) / (sizeof pfn[0]); i++) {
  243. X        resetscroll();
  244. X        clear();
  245. X        (*pfn[i])(gold);    /* a bit dirty 'cause of args */
  246. X        retcont();
  247. X    }
  248. X}
  249. X# endif
  250. END_OF_FILE
  251. if test 7074 -ne `wc -c <'bill.c'`; then
  252.     echo shar: \"'bill.c'\" unpacked with wrong size!
  253. fi
  254. # end of 'bill.c'
  255. fi
  256. if test -f 'global.c' -a "${1}" != "-c" ; then 
  257.   echo shar: Will not clobber existing file \"'global.c'\"
  258. else
  259. echo shar: Extracting \"'global.c'\" \(17640 characters\)
  260. sed "s/^X//" >'global.c' <<'END_OF_FILE'
  261. X/*  global.c        Larn is copyrighted 1986 by Noah Morgan.
  262. X *
  263. X *  raiselevel()        subroutine to raise the player one level
  264. X *  loselevel()     subroutine to lower the player by one level
  265. X *  raiseexperience(x)  subroutine to increase experience points
  266. X *  loseexperience(x)   subroutine to lose experience points
  267. X *  losehp(x)           subroutine to remove hit points from the player
  268. X *  losemhp(x)          subroutine to remove max # hit points from the player
  269. X *  raisehp(x)          subroutine to gain hit points
  270. X *  raisemhp(x)         subroutine to gain maximum hit points
  271. X *  losemspells(x)      subroutine to lose maximum spells
  272. X *  raisemspells(x)     subroutine to gain maximum spells
  273. X *  makemonst(lev)      function to return monster number for a randomly selected monster
  274. X *  positionplayer()    function to be sure player is not in a wall
  275. X *  recalc()            function to recalculate the armor class of the player
  276. X *  quit()              subroutine to ask if the player really wants to quit
  277. X *  more()
  278. X *  take()
  279. X *  drop_object()
  280. X *  enchantarmor()
  281. X *  enchweapon()
  282. X *  pocketfull()
  283. X *  nearbymonst()
  284. X *  stealsomething()
  285. X *  emptyhanded()
  286. X *  creategem()
  287. X *  adjustcvalues()
  288. X *  gettokstr()
  289. X *  getpassword()
  290. X *  getyn()
  291. X *  packweight()
  292. X */
  293. X
  294. X#include "header.h"
  295. Xextern int score[],srcount,dropflag;
  296. Xextern short playerx,playery,lastnum;
  297. Xextern char cheat,level,monstnamelist[];
  298. Xextern char lastmonst[],*what[],*who[]; 
  299. Xextern char winner[];
  300. Xextern char logname[],monstlevel[];
  301. Xextern char sciv[SCORESIZE+1][26][2],*potionname[],*scrollname[];
  302. X
  303. X/*
  304. X    raiselevel()
  305. X
  306. X    subroutine to raise the player one level
  307. X    uses the skill[] array to find level boundarys
  308. X    uses c[EXPERIENCE]  c[LEVEL]
  309. X */
  310. Xraiselevel()
  311. X    {
  312. X    if (c[LEVEL] < MAXPLEVEL) raiseexperience((long)(skill[c[LEVEL]]-c[EXPERIENCE]));
  313. X    }
  314. X
  315. X/*
  316. X    loselevel()
  317. X
  318. X    subroutine to lower the players character level by one
  319. X */
  320. Xloselevel()
  321. X    {
  322. X    if (c[LEVEL] > 1) loseexperience((long)(c[EXPERIENCE] - skill[c[LEVEL]-1] + 1));
  323. X    }
  324. X
  325. X/*
  326. X    raiseexperience(x)
  327. X
  328. X    subroutine to increase experience points
  329. X */
  330. Xraiseexperience(x)
  331. X    register long x;
  332. X    {
  333. X    register int i,tmp;
  334. X    i=c[LEVEL]; c[EXPERIENCE]+=x;
  335. X    while (c[EXPERIENCE] >= skill[c[LEVEL]] && (c[LEVEL] < MAXPLEVEL))
  336. X        {
  337. X        tmp = (c[CONSTITUTION]-c[HARDGAME])>>1;
  338. X        c[LEVEL]++; raisemhp((int)(rnd(3)+rnd((tmp>0)?tmp:1)));
  339. X        raisemspells((int)rund(3));
  340. X        if (c[LEVEL] < 7-c[HARDGAME]) raisemhp((int)(c[CONSTITUTION]>>2));
  341. X        }
  342. X    if (c[LEVEL] != i)
  343. X        {
  344. X        cursors();
  345. X        beep(); lprintf("\nWelcome to level %d",(long)c[LEVEL]);    /* if we changed levels */
  346. X        }
  347. X    bottomline();
  348. X    }
  349. X
  350. X/*
  351. X    loseexperience(x)
  352. X
  353. X    subroutine to lose experience points
  354. X */
  355. Xloseexperience(x)
  356. X    register long x;
  357. X    {
  358. X    register int i,tmp;
  359. X    i=c[LEVEL];     c[EXPERIENCE]-=x;
  360. X    if (c[EXPERIENCE] < 0) c[EXPERIENCE]=0;
  361. X    while (c[EXPERIENCE] < skill[c[LEVEL]-1])
  362. X        {
  363. X        if (--c[LEVEL] <= 1) c[LEVEL]=1;    /*  down one level      */
  364. X        tmp = (c[CONSTITUTION]-c[HARDGAME])>>1; /* lose hpoints */
  365. X        losemhp((int)rnd((tmp>0)?tmp:1));   /* lose hpoints */
  366. X        if (c[LEVEL] < 7-c[HARDGAME]) losemhp((int)(c[CONSTITUTION]>>2));
  367. X        losemspells((int)rund(3));              /*  lose spells     */
  368. X        }
  369. X    if (i!=c[LEVEL])
  370. X        {
  371. X        cursors();
  372. X        beep(); lprintf("\nYou went down to level %d!",(long)c[LEVEL]);
  373. X        }
  374. X    bottomline();
  375. X    }
  376. X
  377. X/*
  378. X    losehp(x)
  379. X    losemhp(x)
  380. X
  381. X    subroutine to remove hit points from the player
  382. X    warning -- will kill player if hp goes to zero
  383. X */
  384. Xlosehp(x)
  385. X    register int x;
  386. X    {
  387. X    if ((c[HP] -= x) <= 0)
  388. X        {
  389. X        beep(); lprcat("\n");  nap(3000);  died(lastnum);
  390. X        }
  391. X    }
  392. X
  393. Xlosemhp(x)
  394. X    register int x;
  395. X    {
  396. X    c[HP] -= x;     if (c[HP] < 1)      c[HP]=1;
  397. X    c[HPMAX] -= x;  if (c[HPMAX] < 1)   c[HPMAX]=1;
  398. X    }
  399. X
  400. X/*
  401. X    raisehp(x)
  402. X    raisemhp(x)
  403. X
  404. X    subroutine to gain maximum hit points
  405. X */
  406. Xraisehp(x)
  407. X    register int x;
  408. X    {
  409. X    if ((c[HP] += x) > c[HPMAX]) c[HP] = c[HPMAX];
  410. X    }
  411. X
  412. Xraisemhp(x)
  413. X    register int x;
  414. X    {
  415. X    c[HPMAX] += x;  c[HP] += x;
  416. X    }
  417. X
  418. X/*
  419. X    raisemspells(x)
  420. X
  421. X    subroutine to gain maximum spells
  422. X*/
  423. Xraisemspells(x)
  424. X    register int x;
  425. X    {
  426. X    c[SPELLMAX]+=x; c[SPELLS]+=x;
  427. X    }
  428. X
  429. X/*
  430. X    losemspells(x)
  431. X
  432. X    subroutine to lose maximum spells
  433. X*/
  434. Xlosemspells(x)
  435. X    register int x;
  436. X    {
  437. X    if ((c[SPELLMAX] -= x) < 0) c[SPELLMAX]=0;
  438. X    if ((c[SPELLS] -= x) < 0) c[SPELLS]=0;
  439. X    }
  440. X
  441. X/*
  442. X    makemonst(lev)
  443. X        int lev;
  444. X
  445. X    function to return monster number for a randomly selected monster
  446. X        for the given cave level    
  447. X */
  448. Xmakemonst(lev)
  449. X    register int lev;
  450. X    {
  451. X    register int tmp,x;
  452. X    if (lev < 1)
  453. X    lev = 1;
  454. X    if (lev > 12)
  455. X    lev = 12;
  456. X    if (lev < 5)
  457. X    tmp=rnd((x=monstlevel[lev-1])?x:1);
  458. X    else
  459. X        tmp=rnd((x=monstlevel[lev-1]-monstlevel[lev-4])?x:1)+monstlevel[lev-4];
  460. X
  461. X    while (monster[tmp].genocided && tmp<MAXMONST)
  462. X    tmp++; /* genocided? */
  463. X    return(tmp);
  464. X    }
  465. X
  466. X/*
  467. X    positionplayer()
  468. X
  469. X    function to be sure player is not in a wall
  470. X */
  471. Xpositionplayer()
  472. X    {
  473. X    int try;
  474. X    try = 2;
  475. X    while ((item[playerx][playery] || mitem[playerx][playery]) && (try))
  476. X        if (++playerx >= MAXX-1)
  477. X            {
  478. X            playerx = 1;
  479. X            if (++playery >= MAXY-1)
  480. X                {   playery = 1;    --try;  }
  481. X            }
  482. X    if (try==0)  lprcat("Failure in positionplayer\n");
  483. X    }
  484. X
  485. X/*
  486. X    recalc()    function to recalculate the armor class of the player
  487. X */
  488. Xrecalc()
  489. X    {
  490. X    register int i,j,k;
  491. X    c[AC] = c[MOREDEFENSES];
  492. X    if (c[WEAR] >= 0)  
  493. X        switch(iven[c[WEAR]])
  494. X            {
  495. X            case OSHIELD:       c[AC] += 2 + ivenarg[c[WEAR]]; break;
  496. X            case OLEATHER:      c[AC] += 2 + ivenarg[c[WEAR]]; break;
  497. X            case OSTUDLEATHER:  c[AC] += 3 + ivenarg[c[WEAR]]; break;
  498. X            case ORING:         c[AC] += 5 + ivenarg[c[WEAR]]; break;
  499. X            case OCHAIN:        c[AC] += 6 + ivenarg[c[WEAR]]; break;
  500. X            case OSPLINT:       c[AC] += 7 + ivenarg[c[WEAR]]; break;
  501. X            case OPLATE:        c[AC] += 9 + ivenarg[c[WEAR]]; break;
  502. X            case OPLATEARMOR:   c[AC] += 10 + ivenarg[c[WEAR]]; break;
  503. X            case OSSPLATE:      c[AC] += 12 + ivenarg[c[WEAR]]; break;
  504. X            }
  505. X
  506. X    if (c[SHIELD] >= 0) if (iven[c[SHIELD]] == OSHIELD) c[AC] += 2 + ivenarg[c[SHIELD]];
  507. X    if (c[WIELD] < 0)  c[WCLASS] = 0;  else
  508. X        {
  509. X        i = ivenarg[c[WIELD]];
  510. X        switch(iven[c[WIELD]])
  511. X            {
  512. X            case ODAGGER:    c[WCLASS] =  3 + i;  break;
  513. X            case OBELT:      c[WCLASS] =  7 + i;  break;
  514. X            case OSHIELD:    c[WCLASS] =  8 + i;  break;
  515. X            case OSPEAR:     c[WCLASS] = 10 + i;  break;
  516. X            case OFLAIL:     c[WCLASS] = 14 + i;  break;
  517. X            case OBATTLEAXE: c[WCLASS] = 17 + i;  break;
  518. X            case OLANCE:     c[WCLASS] = 19 + i;  break;
  519. X            case OLONGSWORD: c[WCLASS] = 22 + i;  break;
  520. X            case O2SWORD:    c[WCLASS] = 26 + i;  break;
  521. X            case OSWORD:     c[WCLASS] = 32 + i;  break;
  522. X            case OSWORDofSLASHING: c[WCLASS] = 30 + i; break;
  523. X            case OHAMMER:    c[WCLASS] = 35 + i;  break;
  524. X            default:         c[WCLASS] = 0;
  525. X            }
  526. X        }
  527. X    c[WCLASS] += c[MOREDAM];
  528. X
  529. X/*  now for regeneration abilities based on rings   */
  530. X    c[REGEN]=1;     c[ENERGY]=0;
  531. X    j=0;  for (k=25; k>0; k--)  if (iven[k]) {j=k; k=0; }
  532. X    for (i=0; i<=j; i++)
  533. X        {
  534. X        switch(iven[i])
  535. X            {
  536. X            case OPROTRING: c[AC]     += ivenarg[i] + 1;    break;
  537. X            case ODAMRING:  c[WCLASS] += ivenarg[i] + 1;    break;
  538. X            case OBELT:     c[WCLASS] += ((ivenarg[i]<<1)) + 2; break;
  539. X
  540. X            case OREGENRING:    c[REGEN]  += ivenarg[i] + 1;    break;
  541. X            case ORINGOFEXTRA:  c[REGEN]  += 5 * (ivenarg[i]+1); break;
  542. X            case OENERGYRING:   c[ENERGY] += ivenarg[i] + 1;    break;
  543. X            }
  544. X        }
  545. X    }
  546. X
  547. X
  548. X/*
  549. X    quit()
  550. X
  551. X    subroutine to ask if the player really wants to quit
  552. X */
  553. Xquit()
  554. X    {
  555. X    register int i;
  556. X    cursors();  strcpy(lastmonst,"");
  557. X    lprcat("\n\nDo you really want to quit?");
  558. X    while (1)
  559. X        {
  560. X        i=ttgetch();
  561. X        if (i == 'y')   { died(300); return; }
  562. X        if ((i == 'n') || (i == '\33')) { lprcat(" no"); lflush(); return; }
  563. X        lprcat("\n");  setbold();  lprcat("Yes");  resetbold();  lprcat(" or ");
  564. X        setbold();  lprcat("No");  resetbold();  lprcat(" please?   Do you want to quit? ");
  565. X        }   
  566. X    }
  567. X
  568. X/*
  569. X    function to ask --more-- then the user must enter a space
  570. X */
  571. Xmore()
  572. X    {
  573. X    lprcat("\n  --- press ");  standout("space");  lprcat(" to continue --- ");
  574. X    while (ttgetch() != ' ');
  575. X    }
  576. X
  577. X/*
  578. X    function to put something in the players inventory
  579. X    returns 0 if success, 1 if a failure
  580. X */
  581. Xtake(itm,arg)
  582. X    int itm,arg;
  583. X    {
  584. X    register int i,limit;
  585. X/*  cursors(); */
  586. X    if ((limit = 15+(c[LEVEL]>>1)) > 26)  limit=26;
  587. X    for (i=0; i<limit; i++)
  588. X        if (iven[i]==0)
  589. X            {
  590. X            iven[i] = itm;  ivenarg[i] = arg;  limit=0;
  591. X            switch(itm)
  592. X                {
  593. X                case OPROTRING: case ODAMRING: case OBELT: limit=1;  break;
  594. X                case ODEXRING:      c[DEXTERITY] += ivenarg[i]+1; limit=1;  break;
  595. X                case OSTRRING:      c[STREXTRA]  += ivenarg[i]+1;   limit=1; break;
  596. X                case OCLEVERRING:   c[INTELLIGENCE] += ivenarg[i]+1;  limit=1; break;
  597. X                case OHAMMER:       c[DEXTERITY] += 10; c[STREXTRA]+=10;
  598. X                                    c[INTELLIGENCE]-=10;    limit=1;     break;
  599. X
  600. X                case OORBOFDRAGON:  c[SLAYING]++;       break;
  601. X                case OSPIRITSCARAB: c[NEGATESPIRIT]++;  break;
  602. X                case OCUBEofUNDEAD: c[CUBEofUNDEAD]++;  break;
  603. X                case ONOTHEFT:      c[NOTHEFT]++;       break;
  604. X                case OSWORDofSLASHING:  c[DEXTERITY] +=5;   limit=1; break;
  605. X                };
  606. X            lprcat("\nYou pick up:"); srcount=0;  show3(i);
  607. X            if (limit) bottomline();  return(0);
  608. X            }
  609. X    lprcat("\nYou can't carry anything else");  return(1);
  610. X    }
  611. X
  612. X/*
  613. X    subroutine to drop an object  returns 1 if something there already else 0
  614. X */
  615. Xdrop_object(k)
  616. X    int k;
  617. X    {
  618. X    int itm;
  619. X    if ((k<0) || (k>25)) return(0);
  620. X    itm = iven[k];  cursors();
  621. X    if (itm==0) { lprintf("\nYou don't have item %c! ",k+'a'); return(1); }
  622. X    if (item[playerx][playery])
  623. X        { beep(); lprcat("\nThere's something here already"); return(1); }
  624. X    if (playery==MAXY-1 && playerx==33) return(1); /* not in entrance */
  625. X    item[playerx][playery] = itm;
  626. X    iarg[playerx][playery] = ivenarg[k];
  627. X    srcount=0; lprcat("\n  You drop:"); show3(k); /* show what item you dropped*/
  628. X    know[playerx][playery] = 0;  iven[k]=0; 
  629. X    if (c[WIELD]==k) c[WIELD]= -1;      if (c[WEAR]==k)  c[WEAR] = -1;
  630. X    if (c[SHIELD]==k) c[SHIELD]= -1;
  631. X    adjustcvalues(itm,ivenarg[k]);
  632. X    dropflag=1; /* say dropped an item so wont ask to pick it up right away */
  633. X    return(0);
  634. X    }
  635. X
  636. X/*
  637. X    function to enchant armor player is currently wearing
  638. X */
  639. Xenchantarmor()
  640. X    {
  641. X    register int tmp;
  642. X    if (c[WEAR]<0) { if (c[SHIELD] < 0)
  643. X        { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; }
  644. X                    else { tmp=iven[c[SHIELD]]; if (tmp != OSCROLL) if (tmp != OPOTION) { ivenarg[c[SHIELD]]++; bottomline(); } } }
  645. X    tmp = iven[c[WEAR]];
  646. X    if (tmp!=OSCROLL) if (tmp!=OPOTION)  { ivenarg[c[WEAR]]++;  bottomline(); }
  647. X    }
  648. X
  649. X/*
  650. X    function to enchant a weapon presently being wielded
  651. X */
  652. Xenchweapon()
  653. X    {
  654. X    register int tmp;
  655. X    if (c[WIELD]<0)
  656. X        { cursors(); beep(); lprcat("\nYou feel a sense of loss"); return; }
  657. X    tmp = iven[c[WIELD]];
  658. X    if (tmp!=OSCROLL) if (tmp!=OPOTION)
  659. X        { ivenarg[c[WIELD]]++;
  660. X          if (tmp==OCLEVERRING) c[INTELLIGENCE]++;  else
  661. X          if (tmp==OSTRRING)    c[STREXTRA]++;  else
  662. X          if (tmp==ODEXRING)    c[DEXTERITY]++;       bottomline(); }
  663. X    }
  664. X
  665. X/*
  666. X    routine to tell if player can carry one more thing
  667. X    returns 1 if pockets are full, else 0
  668. X */
  669. Xpocketfull()
  670. X    {
  671. X    register int i,limit; 
  672. X    if ((limit = 15+(c[LEVEL]>>1)) > 26)  limit=26;
  673. X    for (i=0; i<limit; i++) if (iven[i]==0) return(0);
  674. X    return(1);
  675. X    }
  676. X
  677. X/*
  678. X    function to return 1 if a monster is next to the player else returns 0
  679. X */
  680. Xnearbymonst()
  681. X    {
  682. X    register int tmp,tmp2;
  683. X    for (tmp=playerx-1; tmp<playerx+2; tmp++)
  684. X        for (tmp2=playery-1; tmp2<playery+2; tmp2++)
  685. X            if (mitem[tmp][tmp2]) return(1); /* if monster nearby */
  686. X    return(0);
  687. X    }
  688. X
  689. X/*
  690. X    function to steal an item from the players pockets
  691. X    returns 1 if steals something else returns 0
  692. X */
  693. Xstealsomething()
  694. X    {
  695. X    register int i,j;
  696. X    j=100;
  697. X    while (1)
  698. X        {
  699. X        i=rund(26);
  700. X        if (iven[i]) if (c[WEAR]!=i) if (c[WIELD]!=i) if (c[SHIELD]!=i)
  701. X            {
  702. X            srcount=0; show3(i);
  703. X            adjustcvalues(iven[i],ivenarg[i]);  iven[i]=0; return(1);
  704. X            }
  705. X        if (--j <= 0) return(0);
  706. X        }
  707. X    }
  708. X
  709. X/*
  710. X    function to return 1 is player carrys nothing else return 0
  711. X */
  712. Xemptyhanded()
  713. X    {
  714. X    register int i;
  715. X    for (i=0; i<26; i++)
  716. X        if (iven[i]) if (i!=c[WIELD]) if (i!=c[WEAR]) if (i!=c[SHIELD]) return(0);
  717. X    return(1);
  718. X    }
  719. X
  720. X/*
  721. X    function to create a gem on a square near the player
  722. X */
  723. Xcreategem()
  724. X    {
  725. X    register int i,j;
  726. X    switch(rnd(4))
  727. X        {
  728. X        case 1:  i=ODIAMOND;    j=50;   break;
  729. X        case 2:  i=ORUBY;       j=40;   break;
  730. X        case 3:  i=OEMERALD;    j=30;   break;
  731. X        default: i=OSAPPHIRE;   j=20;   break;
  732. X        };
  733. X    createitem(i,rnd(j)+j/10);
  734. X    }
  735. X
  736. X/*
  737. X    function to change character levels as needed when dropping an object
  738. X    that affects these characteristics
  739. X */
  740. Xadjustcvalues(itm,arg)
  741. X    int itm,arg;
  742. X    {
  743. X    register int flag;
  744. X    flag=0;
  745. X    switch(itm)
  746. X        {
  747. X        case ODEXRING:  c[DEXTERITY] -= arg+1;  flag=1; break;
  748. X        case OSTRRING:  c[STREXTRA]  -= arg+1;  flag=1; break;
  749. X        case OCLEVERRING: c[INTELLIGENCE] -= arg+1;  flag=1; break;
  750. X        case OHAMMER:   c[DEXTERITY] -= 10; c[STREXTRA] -= 10;
  751. X                        c[INTELLIGENCE] += 10; flag=1; break;
  752. X        case OSWORDofSLASHING:  c[DEXTERITY] -= 5;  flag=1; break;
  753. X        case OORBOFDRAGON:      --c[SLAYING];       return;
  754. X        case OSPIRITSCARAB:     --c[NEGATESPIRIT];  return;
  755. X        case OCUBEofUNDEAD:     --c[CUBEofUNDEAD];  return;
  756. X        case ONOTHEFT:          --c[NOTHEFT];       return;
  757. X        case OLANCE:        c[LANCEDEATH]=0;    return;
  758. X        case OPOTION:   case OSCROLL:   return;
  759. X
  760. X        default:    flag=1;
  761. X        };
  762. X    if (flag) bottomline();
  763. X    }
  764. X
  765. X/*
  766. X    function to ask user for a password (no echo)
  767. X    returns 1 if entered correctly, 0 if not
  768. X */
  769. Xstatic char gpwbuf[33];
  770. Xgetpassword()
  771. X    {
  772. X    register int i,j;
  773. X    register char *gpwp;
  774. X    extern char *password;
  775. X    scbr(); /*  system("stty -echo cbreak"); */
  776. X    gpwp = gpwbuf;  lprcat("\nEnter Password: "); lflush();
  777. X    i = strlen(password);
  778. X    for (j=0; j<i; j++) 
  779. X        *gpwp++ = ttgetch();
  780. X    gpwbuf[i]=0;
  781. X    sncbr(); /* system("stty echo -cbreak"); */
  782. X    if (strcmp(gpwbuf,password) != 0)
  783. X        {   lprcat("\nSorry\n");  lflush(); return(0);  }
  784. X    else  return(1);
  785. X    }
  786. X
  787. X/*
  788. X    subroutine to get a yes or no response from the user
  789. X    returns y or n
  790. X */
  791. Xgetyn()
  792. X    {
  793. X    register int i;
  794. X    i=0; while (i!='y' && i!='n' && i!='\33') i=ttgetch();
  795. X    return(i);
  796. X    }
  797. X
  798. X/*
  799. X    function to calculate the pack weight of the player
  800. X    returns the number of pounds the player is carrying
  801. X */
  802. Xpackweight()
  803. X    {
  804. X    register int i,j,k;
  805. X    k=c[GOLD]/1000; j=25;  while ((iven[j]==0) && (j>0)) --j;
  806. X    for (i=0; i<=j; i++)
  807. X        switch(iven[i])
  808. X            {
  809. X            case 0:                                             break;
  810. X            case OSSPLATE:   case OPLATEARMOR:      k += 40;    break;
  811. X            case OPLATE:                            k += 35;    break;
  812. X            case OHAMMER:                           k += 30;    break;
  813. X            case OSPLINT:                           k += 26;    break;
  814. X            case OSWORDofSLASHING:  case OCHAIN:
  815. X            case OBATTLEAXE:        case O2SWORD:   k += 23;    break;
  816. X            case OLONGSWORD:        case OSWORD:
  817. X            case ORING:             case OFLAIL:    k += 20;    break;
  818. X            case OLANCE:        case OSTUDLEATHER:  k += 15;    break;
  819. X            case OLEATHER:          case OSPEAR:    k += 8;     break;
  820. X            case OORBOFDRAGON:      case OBELT:     k += 4;     break;
  821. X            case OSHIELD:                           k += 7;     break;
  822. X            case OCHEST:        k += 30 + ivenarg[i];           break;
  823. X            default:                                k++;
  824. X            };
  825. X    return(k);
  826. X    }
  827. X
  828. X#ifndef MACRORND
  829. X    /* macros to generate random numbers   1<=rnd(N)<=N   0<=rund(N)<=N-1 */
  830. Xrnd(x)
  831. X    int x;
  832. X    {
  833. X    return((((lrandx=lrandx*1103515245+12345)>>7)%(x))+1);
  834. X    }
  835. X
  836. Xrund(x)
  837. X    int x;
  838. X    {
  839. X    return((((lrandx=lrandx*1103515245+12345)>>7)%(x))  );
  840. X    }
  841. X#endif MACRORND
  842. X
  843. X/*
  844. X    function to read a string from token input "string"
  845. X    returns a pointer to the string
  846. X */
  847. Xgettokstr(str)
  848. X    register char *str;
  849. X    {
  850. X    register int i,j;
  851. X    i=50;
  852. X    while ((ttgetch() != '"') && (--i > 0));
  853. X    i=36;
  854. X    while (--i > 0)
  855. X        {
  856. X        if ((j=ttgetch()) != '"') *str++ = j;  else i=0;
  857. X        }
  858. X    *str = 0;
  859. X    i=50;
  860. X    if (j != '"') while ((ttgetch() != '"') && (--i > 0)); /* if end due to too long, then find closing quote */
  861. X    }
  862. END_OF_FILE
  863. if test 17640 -ne `wc -c <'global.c'`; then
  864.     echo shar: \"'global.c'\" unpacked with wrong size!
  865. fi
  866. # end of 'global.c'
  867. fi
  868. if test -f 'io.c' -a "${1}" != "-c" ; then 
  869.   echo shar: Will not clobber existing file \"'io.c'\"
  870. else
  871. echo shar: Extracting \"'io.c'\" \(25801 characters\)
  872. sed "s/^X//" >'io.c' <<'END_OF_FILE'
  873. X/* io.c             Larn is copyrighted 1986 by Noah Morgan.
  874. X *
  875. X *    Below are the functions in this file:
  876. X *
  877. X *    setupvt100()     Subroutine to set up terminal in correct mode for game
  878. X *    clearvt100()      Subroutine to clean up terminal when the game is over
  879. X *    ttgetch()         Routine to read in one character from the terminal
  880. X *    scbr()            Function to set cbreak -echo for the terminal
  881. X *    sncbr()            Function to set -cbreak echo for the terminal
  882. X *    newgame()         Subroutine to save the initial time and seed rnd()
  883. X *
  884. X *    FILE OUTPUT ROUTINES
  885. X *
  886. X *    lprintf(format,args . . .)    printf to the output buffer
  887. X *    lprint(integer)            send binary integer to output buffer
  888. X *    lwrite(buf,len)            write a buffer to the output buffer
  889. X *    lprcat(str)            sent string to output buffer
  890. X *
  891. X *    FILE OUTPUT MACROS (in header.h)
  892. X *
  893. X *    lprc(character)            put the character into the output buffer
  894. X *
  895. X *    FILE INPUT ROUTINES
  896. X *
  897. X *    long lgetc()            read one character from input buffer
  898. X *    long lrint()            read one integer from input buffer
  899. X *    lrfill(address,number)        put input bytes into a buffer
  900. X *    char *lgetw()            get a whitespace ended word from input
  901. X *    char *lgetl()            get a \n or EOF ended line from input
  902. X *
  903. X *    FILE OPEN / CLOSE ROUTINES
  904. X *
  905. X *    lcreat(filename)        create a new file for write
  906. X *    lopen(filename)            open a file for read
  907. X *    lappend(filename)        open for append to an existing file
  908. X *    lrclose()            close the input file
  909. X *    lwclose()            close output file
  910. X *    lflush()            flush the output buffer
  911. X *
  912. X *    Other Routines
  913. X *
  914. X *    cursor(x,y)        position cursor at [x,y]
  915. X *    cursors()        position cursor at [1,24] (saves memory)
  916. X *     cl_line(x,y)             Clear line at [1,y] and leave cursor at [x,y]
  917. X *     cl_up(x,y)            Clear screen from [x,1] to current line.
  918. X *     cl_dn(x,y)         Clear screen from [1,y] to end of display. 
  919. X *     standout(str)         Print the string in standout mode.
  920. X *     set_score_output()     Called when output should be literally printed.
  921. X **    ttputch(ch)        Print one character in decoded output buffer.
  922. X **    flush_buf()        Flush buffer with decoded output.
  923. X **    init_term()        Terminal initialization -- setup termcap info
  924. X **    char *tmcapcnv(sd,ss)      Routine to convert VT100 \33's to termcap format
  925. X *    beep()            Routine to emit a beep if enabled (see no-beep in .larnopts)
  926. X *
  927. X * Note: ** entries are available only in termcap mode.
  928. X */
  929. X
  930. X#include "header.h"
  931. X#include <ctype.h>
  932. X
  933. X#ifdef SYSV    /* system III or system V */
  934. X# ifndef MSDOS
  935. X#   include <termio.h>
  936. X# endif
  937. X#define sgttyb termio
  938. X#define stty(_a,_b) ioctl(_a,TCSETA,_b)
  939. X#define gtty(_a,_b) ioctl(_a,TCGETA,_b)
  940. Xstatic int rawflg = 0;
  941. Xstatic char saveeof,saveeol;
  942. X#define doraw(_a) if(!rawflg){++rawflg;saveeof=_a.c_cc[VMIN];saveeol=_a.c_cc[VTIME];}\
  943. X    _a.c_cc[VMIN]=1;_a.c_cc[VTIME]=1;_a.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL)
  944. X#define unraw(_a) _a.c_cc[VMIN]=saveeof;_a.c_cc[VTIME]=saveeol;_a.c_lflag |= ICANON|ECHO|ECHOE|ECHOK|ECHONL
  945. X#else not SYSV
  946. X#ifdef VMS
  947. X#include    <descrip.h>
  948. X#include    <ssdef.h>
  949. X#include    <stsdef.h>
  950. X#include    <iodef.h>
  951. X#include    <ttdef.h>
  952. X#include    <tt2def.h>
  953. X#else VMS
  954. X#ifndef BSD
  955. X#define CBREAK RAW        /* V7 has no CBREAK */
  956. X#endif
  957. X#define doraw(_a) (_a.sg_flags |= CBREAK,_a.sg_flags &= ~ECHO)
  958. X#define unraw(_a) (_a.sg_flags &= ~CBREAK,_a.sg_flags |= ECHO)
  959. X#include <sgtty.h>
  960. X#endif not SYSV
  961. X#endif VMS
  962. X
  963. X#ifndef NOVARARGS    /* if we have varargs */
  964. X#include <varargs.h>
  965. X#else NOVARARGS    /* if we don't have varargs */
  966. Xtypedef char *va_list;
  967. X#define va_dcl int va_alist;
  968. X#define va_start(plist) plist = (char *) &va_alist
  969. X#define va_end(plist)
  970. X#define va_arg(plist,mode) ((mode *)(plist += sizeof(mode)))[-1]
  971. X#endif NOVARARGS
  972. X
  973. X#define LINBUFSIZE 128        /* size of the lgetw() and lgetl() buffer        */
  974. Xint lfd;            /*  output file numbers        */
  975. Xint fd;                /*  input file numbers        */
  976. X# ifndef MSDOS
  977. X# ifndef VMS
  978. Xstatic struct sgttyb ttx;    /* storage for the tty modes                    */
  979. X# else
  980. Xint    iochan;            /* storage for the tty channel    */
  981. Xint    ttx[3];            /* storage for the tty modes    */
  982. Xint    cbflag;            /* cbreak flag.  Set when SCBRd */
  983. X# endif
  984. X# endif
  985. Xstatic int ipoint=MAXIBUF,iepoint=MAXIBUF;    /*  input buffering pointers    */
  986. Xstatic char lgetwbuf[LINBUFSIZE];    /* get line (word) buffer                */
  987. X
  988. X#ifdef DGK_MSDOS
  989. X# include <setjmp.h>
  990. X extern jmp_buf save_jbuf;
  991. X extern int save_mode;
  992. X#endif
  993. X
  994. X# ifdef MSDOS
  995. X# include <fcntl.h>        /* For O_BINARY */
  996. Xstatic int (*getchfn)();
  997. Xint getche(), kgetch();
  998. X# endif
  999. X
  1000. X/*
  1001. X *    setupvt100()         Subroutine to set up terminal in correct mode for game
  1002. X *
  1003. X *    Attributes off, clear screen, set scrolling region, set tty mode 
  1004. X */
  1005. Xsetupvt100()
  1006. X    {
  1007. X#ifdef VMS
  1008. X    struct  dsc$descriptor  idsc;
  1009. X    register int        status;
  1010. X
  1011. X    idsc.dsc$a_pointer = "SYS$COMMAND";
  1012. X    idsc.dsc$w_length  = strlen(idsc.dsc$a_pointer);
  1013. X    idsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  1014. X    idsc.dsc$b_class   = DSC$K_CLASS_S;
  1015. X    status = SYS$ASSIGN(&idsc, &iochan, 0, 0);
  1016. X    if (status&STS$M_SUCCESS == 0)
  1017. X        exit(status);
  1018. X#endif
  1019. X    lprc(T_INIT);
  1020. X    clear();  setscroll();  scbr(); /* system("stty cbreak -echo"); */
  1021. X# ifdef DGK_MSDOS
  1022. X    setraw();
  1023. X    setcursor();
  1024. X
  1025. X    /* Select normal ASCII and line drawing character sets.
  1026. X     */
  1027. X    if (DECRainbow)
  1028. X        lprcat("\033(B\033)0");
  1029. X# endif
  1030. X    }
  1031. X
  1032. X/*
  1033. X *    clearvt100()          Subroutine to clean up terminal when the game is over
  1034. X *
  1035. X *    Attributes off, clear screen, unset scrolling region, restore tty mode 
  1036. X */
  1037. Xclearvt100()
  1038. X    {
  1039. X    lprc(T_END);
  1040. X    resetscroll();  clear();  sncbr(); /* system("stty -cbreak echo"); */
  1041. X# ifdef DGK_MSDOS
  1042. X    unsetraw();
  1043. X    resetcursor();
  1044. X# endif
  1045. X#ifdef VMS
  1046. X    SYS$DASSGN(iochan);
  1047. X#endif
  1048. X    }
  1049. X
  1050. X/*
  1051. X *    ttgetch()         Routine to read in one character from the terminal
  1052. X */
  1053. Xttgetch()
  1054. X    {
  1055. X    char byt;
  1056. X#ifdef EXTRA
  1057. X    c[BYTESIN]++;
  1058. X#endif EXTRA
  1059. X    lflush();        /* be sure output buffer is flushed */
  1060. X# ifdef MSDOS
  1061. X    if ((byt = (*getchfn)()) == '\r')
  1062. X        byt = '\n';
  1063. X    return byt;
  1064. X#endif MSDOS
  1065. X
  1066. X#ifdef VMS
  1067. X        {
  1068. X    extern vms_ttgetch();
  1069. X        return (vms_ttgetch());
  1070. X    }
  1071. X#else VMS
  1072. X    read(0,&byt,1);     /* get byte from terminal */
  1073. X    return(byt);
  1074. X# endif VMS
  1075. X    }
  1076. X
  1077. X/*
  1078. X *    scbr()        Function to set cbreak -echo for the terminal
  1079. X *
  1080. X *    like: system("stty cbreak -echo")
  1081. X */
  1082. Xscbr()
  1083. X    {
  1084. X# ifdef MSDOS
  1085. X    /* Set up to use the direct console input call which may
  1086. X     * read from the keypad;
  1087. X     */
  1088. X    getchfn = kgetch;
  1089. X# else
  1090. X# ifdef VMS
  1091. X    int    status;
  1092. X    int    iosb[2];
  1093. X
  1094. X    cbflag = 1;
  1095. X    status = SYS$QIOW(0, iochan, IO$_SENSEMODE, iosb, 0, 0,
  1096. X              ttx, sizeof(ttx), 0, 0, 0, 0);
  1097. X    if (status&STS$M_SUCCESS == 0)
  1098. X        exit(status);
  1099. X    ttx[1] |= TT$M_NOECHO;
  1100. X    ttx[2] |= TT2$M_PASTHRU;
  1101. X    status = SYS$QIOW(0, iochan, IO$_SETMODE, iosb, 0, 0,
  1102. X              ttx, sizeof(ttx), 0, 0, 0, 0);
  1103. X    if (status&STS$M_SUCCESS == 0)
  1104. X        exit(status);
  1105. X# else
  1106. X    gtty(0,&ttx);        doraw(ttx);        stty(0,&ttx);
  1107. X# endif
  1108. X# endif
  1109. X    }
  1110. X
  1111. X/*
  1112. X *    sncbr()        Function to set -cbreak echo for the terminal
  1113. X *
  1114. X *    like: system("stty -cbreak echo")
  1115. X */
  1116. Xsncbr()
  1117. X    {
  1118. X# ifdef MSDOS
  1119. X    /* Set up to use the direct console input call with echo, getche()
  1120. X     */
  1121. X    getchfn = getche;
  1122. X# else
  1123. X# ifdef VMS
  1124. X    int    status;
  1125. X    int    iosb[2];
  1126. X    cbflag = 0;
  1127. X    status = SYS$QIOW(0, iochan, IO$_SENSEMODE, iosb, 0, 0,
  1128. X              ttx, sizeof(ttx), 0, 0, 0, 0);
  1129. X    if (status&STS$M_SUCCESS == 0)
  1130. X        exit(status);
  1131. X    ttx[1] &= ~TT$M_NOECHO;
  1132. X    ttx[2] &= ~TT2$M_PASTHRU;
  1133. X    status = SYS$QIOW(0, iochan, IO$_SETMODE, iosb, 0, 0,
  1134. X              ttx, sizeof(ttx), 0, 0, 0, 0);
  1135. X    if (status&STS$M_SUCCESS == 0)
  1136. X        exit(status);
  1137. X# else
  1138. X    gtty(0,&ttx);        unraw(ttx);        stty(0,&ttx);
  1139. X# endif
  1140. X# endif
  1141. X    }
  1142. X
  1143. X/*
  1144. X *    newgame()         Subroutine to save the initial time and seed rnd()
  1145. X */
  1146. Xnewgame()
  1147. X{
  1148. X    register long *p,*pe;
  1149. X    for (p=c,pe=c+100; p<pe; *p++ =0);
  1150. X    time(&initialtime);
  1151. X    srand(initialtime);
  1152. X    lcreat((char*)0);    /* open buffering for output to terminal */
  1153. X}
  1154. X
  1155. X/*
  1156. X *    lprintf(format,args . . .)        printf to the output buffer
  1157. X *        char *format;
  1158. X *        ??? args . . .
  1159. X *
  1160. X *    Enter with the format string in "format", as per printf() usage
  1161. X *        and any needed arguments following it
  1162. X *    Note: lprintf() only supports %s, %c and %d, with width modifier and left
  1163. X *        or right justification.
  1164. X *    No correct checking for output buffer overflow is done, but flushes 
  1165. X *        are done beforehand if needed.
  1166. X *    Returns nothing of value.
  1167. X */
  1168. X#ifdef lint
  1169. X/*VARARGS*/
  1170. Xlprintf(str)
  1171. X    char *str;
  1172. X    {
  1173. X    char *str2;
  1174. X    str2 = str;
  1175. X    str = str2; /* to make lint happy */
  1176. X    }
  1177. X/*VARARGS*/
  1178. Xsprintf(str)
  1179. X    char *str;
  1180. X    {
  1181. X    char *str2;
  1182. X    str2 = str;
  1183. X    str = str2; /* to make lint happy */
  1184. X    }
  1185. X#else lint
  1186. X/*VARARGS*/
  1187. Xlprintf(va_alist)
  1188. Xva_dcl
  1189. X    {
  1190. X    va_list ap;    /* pointer for variable argument list */
  1191. X    register char *fmt;
  1192. X    register char *outb,*tmpb;
  1193. X    register long wide,left,cont,n;        /* data for lprintf    */
  1194. X    char db[12];            /* %d buffer in lprintf    */
  1195. X
  1196. X    va_start(ap);    /* initialize the var args pointer */
  1197. X    fmt = va_arg(ap, char *);    /* pointer to format string */
  1198. X    if (lpnt >= lpend) lflush(); 
  1199. X    outb = lpnt;
  1200. X    for ( ; ; )
  1201. X        {
  1202. X        while (*fmt != '%')
  1203. X            if (*fmt) *outb++ = *fmt++;  else { lpnt=outb;  return; }
  1204. X        wide = 0;    left = 1;    cont=1;
  1205. X        while (cont)
  1206. X          switch(*(++fmt))
  1207. X            {
  1208. X            case 'd':    n = va_arg(ap, long);
  1209. X                        if (n<0) { n = -n;  *outb++ = '-';  if (wide) --wide; }
  1210. X                        tmpb = db+11;    *tmpb = (char)(n % 10 + '0');
  1211. X                        while (n>9)  *(--tmpb) = (char)((n /= 10) % 10 + '0');
  1212. X                        if (wide==0)  while (tmpb < db+12) *outb++ = *tmpb++;
  1213. X                        else
  1214. X                            {
  1215. X                            wide -= db-tmpb+12;
  1216. X                            if (left)  while (wide-- > 0) *outb++ = ' ';
  1217. X                            while (tmpb < db+12) *outb++ = *tmpb++;
  1218. X                            if (left==0)  while (wide-- > 0) *outb++ = ' ';
  1219. X                            }
  1220. X                        cont=0;    break;
  1221. X
  1222. X            case 's':    tmpb = va_arg(ap, char *);
  1223. X                        if (wide==0)  { while (*outb++ = *tmpb++);  --outb; } 
  1224. X                        else
  1225. X                            {
  1226. X                            n = wide - strlen(tmpb);
  1227. X                            if (left)  while (n-- > 0) *outb++ = ' ';
  1228. X                            while (*outb++ = *tmpb++);  --outb;
  1229. X                            if (left==0)  while (n-- > 0) *outb++ = ' ';
  1230. X                            }
  1231. X                        cont=0;    break;
  1232. X
  1233. X            case 'c':    *outb++ = va_arg(ap, int);    cont=0;  break;
  1234. X
  1235. X            case '0':
  1236. X            case '1':
  1237. X            case '2':
  1238. X            case '3':
  1239. X            case '4':
  1240. X            case '5':
  1241. X            case '6':
  1242. X            case '7':
  1243. X            case '8':
  1244. X            case '9':    wide = 10*wide + *fmt - '0';    break;
  1245. X
  1246. X            case '-':    left = 0;    break;
  1247. X
  1248. X            default:    *outb++ = *fmt;  cont=0;    break;
  1249. X            };
  1250. X        fmt++;
  1251. X        }
  1252. X    va_end(ap);
  1253. X    }
  1254. X#endif lint
  1255. X
  1256. X/*
  1257. X *    lprint(long-integer)                send binary integer to output buffer
  1258. X *        long integer;
  1259. X *
  1260. X *        +---------+---------+---------+---------+
  1261. X *        |    high  |            |          |      low    |
  1262. X *        |  order  |            |          |  order    |
  1263. X *        |   byte  |            |          |      byte    |
  1264. X *        +---------+---------+---------+---------+
  1265. X *       31  ---  24 23 --- 16 15 ---  8 7  ---   0
  1266. X *
  1267. X *    The save order is low order first, to high order (4 bytes total)
  1268. X *        and is written to be system independent.
  1269. X *    No checking for output buffer overflow is done, but flushes if needed!
  1270. X *    Returns nothing of value.
  1271. X */
  1272. Xlprint(x)
  1273. X    register long x;
  1274. X    {
  1275. X    if (lpnt >= lpend) lflush();
  1276. X    *lpnt++ =  255 & x;            *lpnt++ =  255 & (x>>8);
  1277. X    *lpnt++ =  255 & (x>>16);    *lpnt++ =  255 & (x>>24);
  1278. X    }
  1279. X
  1280. X/*
  1281. X *    lwrite(buf,len)            write a buffer to the output buffer
  1282. X *        char *buf;
  1283. X *        int len;
  1284. X *    
  1285. X *    Enter with the address and number of bytes to write out
  1286. X *    Returns nothing of value
  1287. X */
  1288. Xlwrite(buf,len)
  1289. X    register char *buf;
  1290. X    int len;
  1291. X    {
  1292. X    register char *str;
  1293. X    register int num2;
  1294. X    if (len > 399)  /* don't copy data if can just write it */
  1295. X        {
  1296. X#ifdef EXTRA
  1297. X        c[BYTESOUT] += len;
  1298. X#endif
  1299. X
  1300. X#ifndef VT100
  1301. X        for (str=buf;  len>0; --len)
  1302. X            lprc(*str++);
  1303. X#else VT100
  1304. X        lflush();
  1305. X        write(lfd,buf,len);
  1306. X#endif VT100
  1307. X        } 
  1308. X    else while (len)
  1309. X        {
  1310. X        if (lpnt >= lpend) lflush();    /* if buffer is full flush it    */
  1311. X        num2 = lpbuf+BUFBIG-lpnt;    /*    # bytes left in output buffer    */
  1312. X        if (num2 > len) num2=len;
  1313. X        str = lpnt;  len -= num2;
  1314. X        while (num2--)  *str++ = *buf++;    /* copy in the bytes */
  1315. X        lpnt = str;
  1316. X        }
  1317. X    }
  1318. X
  1319. X/*
  1320. X *    long lgetc()        Read one character from input buffer
  1321. X *
  1322. X *  Returns 0 if EOF, otherwise the character
  1323. X */
  1324. Xlong lgetc()
  1325. X    {
  1326. X    register int i;
  1327. X
  1328. X    if (ipoint != iepoint)  return(inbuffer[ipoint++]);
  1329. X    if (iepoint!=MAXIBUF)   return(0);
  1330. X    if ((i=vread(fd,inbuffer,MAXIBUF))<=0) {
  1331. X        if (i!=0)
  1332. X            write(1,"error reading from input file\n",30);
  1333. X    iepoint = ipoint = 0;
  1334. X    return(0);
  1335. X    }
  1336. X    ipoint=1;  iepoint=i;  return(*inbuffer);
  1337. X}
  1338. X
  1339. X/*
  1340. X *    long lrint()            Read one integer from input buffer
  1341. X *
  1342. X *        +---------+---------+---------+---------+
  1343. X *        |    high  |            |          |      low    |
  1344. X *        |  order  |            |          |  order    |
  1345. X *        |   byte  |            |          |      byte    |
  1346. X *        +---------+---------+---------+---------+
  1347. X *       31  ---  24 23 --- 16 15 ---  8 7  ---   0
  1348. X *
  1349. X *    The save order is low order first, to high order (4 bytes total)
  1350. X *    Returns the int read
  1351. X */
  1352. Xlong lrint()
  1353. X    {
  1354. X    register unsigned long i;
  1355. X    i  = 255 & lgetc();                i |= (255 & lgetc()) << 8;
  1356. X    i |= (255 & lgetc()) << 16;        i |= (255 & lgetc()) << 24;
  1357. X    return(i);
  1358. X    }
  1359. X
  1360. X/*
  1361. X *    lrfill(address,number)            put input bytes into a buffer
  1362. X *        char *address;
  1363. X *        int number;
  1364. X *
  1365. X *    Reads "number" bytes into the buffer pointed to by "address".
  1366. X *    Returns nothing of value
  1367. X */
  1368. Xlrfill(adr,num)
  1369. X    register char *adr;
  1370. X    int num;
  1371. X    {
  1372. X    register char *pnt;
  1373. X    register int num2;
  1374. X    while (num)
  1375. X        {
  1376. X        if (iepoint == ipoint)
  1377. X            {
  1378. X            if (num>5) /* fast way */
  1379. X                {
  1380. X                if (vread(fd,adr,num) != num)
  1381. X                    write(2,"error reading from input file\n",30);
  1382. X                num=0;
  1383. X                }
  1384. X            else { *adr++ = lgetc();  --num; }
  1385. X            }
  1386. X        else
  1387. X            {
  1388. X            num2 = iepoint-ipoint;    /*    # of bytes left in the buffer    */
  1389. X            if (num2 > num) num2=num;
  1390. X            pnt = inbuffer+ipoint;    num -= num2;  ipoint += num2;
  1391. X            while (num2--)  *adr++ = *pnt++;
  1392. X            }
  1393. X        }
  1394. X    }
  1395. X
  1396. X/*
  1397. X *    char *lgetw()            Get a whitespace ended word from input
  1398. X *
  1399. X *    Returns pointer to a buffer that contains word.  If EOF, returns a NULL
  1400. X */
  1401. Xchar *lgetw()
  1402. X    {
  1403. X    register char *lgp,cc;
  1404. X    register int n=LINBUFSIZE,quote=0;
  1405. X    lgp = lgetwbuf;
  1406. X    do cc=lgetc();  while ((cc <= 32) && (cc > NULL));  /* eat whitespace */
  1407. X    for ( ; ; --n,cc=lgetc())
  1408. X        {
  1409. X        if ((cc==NULL) && (lgp==lgetwbuf))  return(NULL);    /* EOF */
  1410. X        if ((n<=1) || ((cc<=32) && (quote==0))) { *lgp=NULL; return(lgetwbuf); }
  1411. X        if (cc != '"') *lgp++ = cc;   else quote ^= 1;
  1412. X        }
  1413. X    }
  1414. X
  1415. X/*
  1416. X *    char *lgetl()        Function to read in a line ended by newline or EOF
  1417. X *
  1418. X *    Returns pointer to a buffer that contains the line.  If EOF, returns NULL
  1419. X */
  1420. Xchar *lgetl()
  1421. X{
  1422. X    register int i=LINBUFSIZE,ch;
  1423. X    register char *str=lgetwbuf;
  1424. X    for ( ; ; --i) {
  1425. X        *str++ = ch = lgetc();
  1426. X        if (ch == 0) {
  1427. X            if (str == lgetwbuf+1)
  1428. X                return(NULL);    /* EOF */
  1429. X        ot:    *str = 0;
  1430. X            return(lgetwbuf);    /* line ended by EOF */
  1431. X        }
  1432. X        if ((ch=='\n') || (i<=1))
  1433. X            goto ot;        /* line ended by \n */
  1434. X    }
  1435. X}
  1436. X
  1437. X/*
  1438. X *    lcreat(filename)            Create a new file for write
  1439. X *        char *filename;
  1440. X *
  1441. X *    lcreat((char*)0); means to the terminal
  1442. X *    Returns -1 if error, otherwise the file descriptor opened.
  1443. X */
  1444. Xlcreat(str)
  1445. X    char *str;
  1446. X    {
  1447. X    lpnt = lpbuf;    lpend = lpbuf+BUFBIG;
  1448. X    if (str==NULL) return(lfd=1);
  1449. X    if ((lfd=creat(str,0644)) < 0) 
  1450. X        {
  1451. X        lfd=1; lprintf("error creating file <%s>\n",str); lflush(); return(-1);
  1452. X        }
  1453. X# ifdef MSDOS
  1454. X    setmode(lfd, O_BINARY);
  1455. X# endif
  1456. X    return(lfd);
  1457. X    }
  1458. X
  1459. X/*
  1460. X *    lopen(filename)            Open a file for read
  1461. X *        char *filename;
  1462. X *
  1463. X *    lopen(0) means from the terminal
  1464. X *    Returns -1 if error, otherwise the file descriptor opened.
  1465. X */
  1466. Xlopen(str)
  1467. X    char *str;
  1468. X    {
  1469. X    ipoint = iepoint = MAXIBUF;
  1470. X    if (str==NULL) return(fd=0);
  1471. X    if ((fd=open(str,0)) < 0)
  1472. X        {
  1473. X        lwclose(); lfd=1; lpnt=lpbuf; return(-1);
  1474. X        }
  1475. X# ifdef MSDOS
  1476. X    setmode(fd, O_BINARY);
  1477. X# endif
  1478. X    return(fd);
  1479. X    }
  1480. X
  1481. X/*
  1482. X *    lappend(filename)        Open for append to an existing file
  1483. X *        char *filename;
  1484. X *
  1485. X *    lappend(0) means to the terminal
  1486. X *    Returns -1 if error, otherwise the file descriptor opened.
  1487. X */
  1488. Xlappend(str)
  1489. X    char *str;
  1490. X    {
  1491. X    lpnt = lpbuf;    lpend = lpbuf+BUFBIG;
  1492. X    if (str==NULL) return(lfd=1);
  1493. X    if ((lfd=open(str,2)) < 0)
  1494. X        {
  1495. X        lfd=1; return(-1);
  1496. X        }
  1497. X# ifdef MSDOS
  1498. X    setmode(lfd, O_BINARY);
  1499. X# endif
  1500. X    lseek(lfd,0L,2);    /* seek to end of file */
  1501. X    return(lfd);
  1502. X    }
  1503. X
  1504. X/*
  1505. X *    lrclose()                        close the input file
  1506. X *
  1507. X *    Returns nothing of value.
  1508. X */
  1509. Xlrclose()
  1510. X    {
  1511. X    if (fd > 0) close(fd);
  1512. X    }
  1513. X
  1514. X/*
  1515. X *    lwclose()                        close output file flushing if needed
  1516. X *
  1517. X *    Returns nothing of value.
  1518. X */
  1519. Xlwclose()
  1520. X    {
  1521. X    lflush();    if (lfd > 2) close(lfd);
  1522. X    }
  1523. X
  1524. X/*
  1525. X *    lprcat(string)                    append a string to the output buffer
  1526. X *                                    avoids calls to lprintf (time consuming)
  1527. X */
  1528. Xlprcat(str)
  1529. X    register char *str;
  1530. X    {
  1531. X    register char *str2;
  1532. X    if (lpnt >= lpend) lflush(); 
  1533. X    str2 = lpnt;
  1534. X    while (*str2++ = *str++);
  1535. X    lpnt = str2 - 1;
  1536. X    }
  1537. X
  1538. X#ifdef VT100
  1539. X/*
  1540. X *    cursor(x,y)         Subroutine to set the cursor position
  1541. X *
  1542. X *    x and y are the cursor coordinates, and lpbuff is the output buffer where
  1543. X *    escape sequence will be placed. 
  1544. X */
  1545. Xstatic char *y_num[]= { "\33[","\33[","\33[2","\33[3","\33[4","\33[5","\33[6",
  1546. X    "\33[7","\33[8","\33[9","\33[10","\33[11","\33[12","\33[13","\33[14",
  1547. X    "\33[15","\33[16","\33[17","\33[18","\33[19","\33[20","\33[21","\33[22",
  1548. X    "\33[23","\33[24" };
  1549. X
  1550. Xstatic char *x_num[]= { "H","H",";2H",";3H",";4H",";5H",";6H",";7H",";8H",";9H",
  1551. X    ";10H",";11H",";12H",";13H",";14H",";15H",";16H",";17H",";18H",";19H",
  1552. X    ";20H",";21H",";22H",";23H",";24H",";25H",";26H",";27H",";28H",";29H",
  1553. X    ";30H",";31H",";32H",";33H",";34H",";35H",";36H",";37H",";38H",";39H",
  1554. X    ";40H",";41H",";42H",";43H",";44H",";45H",";46H",";47H",";48H",";49H",
  1555. X    ";50H",";51H",";52H",";53H",";54H",";55H",";56H",";57H",";58H",";59H",
  1556. X    ";60H",";61H",";62H",";63H",";64H",";65H",";66H",";67H",";68H",";69H",
  1557. X    ";70H",";71H",";72H",";73H",";74H",";75H",";76H",";77H",";78H",";79H",
  1558. X    ";80H" };
  1559. X
  1560. Xcursor(x,y)
  1561. X    int x,y;
  1562. X    {
  1563. X    register char *p;
  1564. X    if (lpnt >= lpend) lflush();
  1565. X
  1566. X    p = y_num[y];    /* get the string to print */
  1567. X    while (*p) *lpnt++ = *p++;    /* print the string */
  1568. X
  1569. X    p = x_num[x];    /* get the string to print */
  1570. X    while (*p) *lpnt++ = *p++;    /* print the string */
  1571. X    }
  1572. X#else VT100
  1573. X/*
  1574. X * cursor(x,y)      Put cursor at specified coordinates staring at [1,1] (termcap)
  1575. X */
  1576. Xcursor (x,y)
  1577. X    int x,y;
  1578. X    {
  1579. X    if (lpnt >= lpend) lflush ();
  1580. X
  1581. X    *lpnt++ = CURSOR;        *lpnt++ = x;        *lpnt++ = y;
  1582. X    }
  1583. X#endif VT100
  1584. X
  1585. X/*
  1586. X *    Routine to position cursor at beginning of 24th line
  1587. X */
  1588. Xcursors()
  1589. X    {
  1590. X    cursor(1,24);
  1591. X    }
  1592. X
  1593. X#ifndef VT100
  1594. X/*
  1595. X * Warning: ringing the bell is control code 7. Don't use in defines.
  1596. X * Don't change the order of these defines.
  1597. X * Also used in helpfiles. Codes used in helpfiles should be \E[1 to \E[7 with
  1598. X * obvious meanings.
  1599. X */
  1600. X
  1601. Xstatic char cap[256];
  1602. Xstatic char *CM, *CE, *CD, *CL, *SO, *SE, *AL, *DL, *TI, *TE;/* Termcap capabilities */
  1603. Xstatic char *outbuf=0;    /* translated output buffer */
  1604. X
  1605. Xstatic int ttputch ();
  1606. X
  1607. X/*
  1608. X * init_term()        Terminal initialization -- setup termcap info
  1609. X */
  1610. Xinit_term()
  1611. X    {
  1612. X    char termbuf[1024];
  1613. X    char *capptr = cap+10;
  1614. X    char *term;
  1615. X
  1616. X# ifdef MSDOS
  1617. X    term = getenv("TERM");
  1618. X    if (term == NULL)
  1619. X        term = "ibmpc-mono";
  1620. X    switch (tgetent(termbuf, term))
  1621. X# else
  1622. X# ifdef VMS
  1623. X    term = getenv("TERMINAL");
  1624. X    if (term == NULL)
  1625. X        term = getenv("TERM");
  1626. X    switch (tgetent(termbuf, term))
  1627. X# else
  1628. X    switch (tgetent(termbuf, term = getenv("TERM")))
  1629. X# endif
  1630. X# endif
  1631. X        {
  1632. X        case -1: 
  1633. X            write(2, "Cannot open termcap file.\n", 26); exit();
  1634. X        case 0: 
  1635. X            write(2, "Cannot find entry of ", 21);
  1636. X            write(2, term, strlen (term));
  1637. X            write(2, " in termcap\n", 12);
  1638. X            exit();
  1639. X        };
  1640. X
  1641. X    CM = tgetstr("cm", &capptr);  /* Cursor motion */
  1642. X    CE = tgetstr("ce", &capptr);  /* Clear to eoln */
  1643. X    CL = tgetstr("cl", &capptr);  /* Clear screen */
  1644. X
  1645. X/* OPTIONAL */
  1646. X    AL = tgetstr("al", &capptr);  /* Insert line */
  1647. X    DL = tgetstr("dl", &capptr);  /* Delete line */
  1648. X    SO = tgetstr("so", &capptr);  /* Begin standout mode */
  1649. X    SE = tgetstr("se", &capptr);  /* End standout mode */
  1650. X    CD = tgetstr("cd", &capptr);  /* Clear to end of display */
  1651. X    TI = tgetstr("ti", &capptr);  /* Terminal initialization */
  1652. X    TE = tgetstr("te", &capptr);  /* Terminal end */
  1653. X
  1654. X    if (!CM)    /* can't find cursor motion entry */
  1655. X        {
  1656. X        write(2, "Sorry, for a ",13);        write(2, term, strlen(term));
  1657. X        write(2, ", I can't find the cursor motion entry in termcap\n",50);
  1658. X        exit();
  1659. X        }
  1660. X    if (!CE)    /* can't find clear to end of line entry */
  1661. X        {
  1662. X        write(2, "Sorry, for a ",13);        write(2, term, strlen(term));
  1663. X        write(2,", I can't find the clear to end of line entry in termcap\n",57);
  1664. X        exit();
  1665. X        }
  1666. X    if (!CL)    /* can't find clear entire screen entry */
  1667. X        {
  1668. X        write(2, "Sorry, for a ",13);        write(2, term, strlen(term));
  1669. X        write(2, ", I can't find the clear entire screen entry in termcap\n",56);
  1670. X        exit();
  1671. X        }
  1672. X    if ((outbuf=(char *)malloc(BUFBIG+16))==0) /* get memory for decoded output buffer*/
  1673. X        {
  1674. X        write(2,"Error malloc'ing memory for decoded output buffer\n",50);
  1675. X        died(-285);    /* malloc() failure */
  1676. X        }
  1677. X    }
  1678. X#endif VT100
  1679. X
  1680. X/*
  1681. X * cl_line(x,y)  Clear the whole line indicated by 'y' and leave cursor at [x,y]
  1682. X */
  1683. Xcl_line(x,y)
  1684. X    int x,y;
  1685. X    {
  1686. X#ifdef VT100
  1687. X    cursor(x,y);        lprcat("\33[2K");
  1688. X#else VT100
  1689. X    cursor(1,y);        *lpnt++ = CL_LINE;        cursor(x,y);
  1690. X#endif VT100
  1691. X    }
  1692. X
  1693. X/*
  1694. X * cl_up(x,y) Clear screen from [x,1] to current position. Leave cursor at [x,y]
  1695. X */
  1696. Xcl_up(x,y)
  1697. X    register int x,y;
  1698. X    {
  1699. X#ifdef VT100
  1700. X    cursor(x,y);  lprcat("\33[1J\33[2K");
  1701. X#else VT100
  1702. X    register int i;
  1703. X    cursor(1,1);
  1704. X    for (i=1; i<=y; i++)   { *lpnt++ = CL_LINE;  *lpnt++ = '\n'; }
  1705. X    cursor(x,y);
  1706. X#endif VT100
  1707. X    }
  1708. X
  1709. X/*
  1710. X * cl_dn(x,y)     Clear screen from [1,y] to end of display. Leave cursor at [x,y]
  1711. X */
  1712. Xcl_dn(x,y)
  1713. X    register int x,y;
  1714. X    {
  1715. X#ifdef VT100
  1716. X    cursor(x,y); lprcat("\33[J\33[2K");
  1717. X#else VT100
  1718. X    register int i;
  1719. X    cursor(1,y);
  1720. X    if (!CD)
  1721. X        {
  1722. X        *lpnt++ = CL_LINE;
  1723. X        for (i=y; i<=24; i++) { *lpnt++ = CL_LINE;  if (i!=24) *lpnt++ = '\n'; }
  1724. X        cursor(x,y);
  1725. X        }
  1726. X    else
  1727. X        *lpnt++ = CL_DOWN;
  1728. X    cursor(x,y);
  1729. X#endif VT100
  1730. X    }
  1731. X
  1732. X/*
  1733. X * standout(str)    Print the argument string in inverse video (standout mode).
  1734. X */
  1735. Xstandout(str)
  1736. X    register char *str;
  1737. X    {
  1738. X#ifdef VT100
  1739. X    setbold();
  1740. X    while (*str)
  1741. X        *lpnt++ = *str++;
  1742. X    resetbold();
  1743. X#else VT100
  1744. X    *lpnt++ = ST_START;
  1745. X    while (*str)
  1746. X        *lpnt++ = *str++;
  1747. X    *lpnt++ = ST_END;
  1748. X#endif VT100
  1749. X    }
  1750. X
  1751. X/*
  1752. X * set_score_output()     Called when output should be literally printed.
  1753. X */
  1754. Xset_score_output()
  1755. X    {
  1756. X    enable_scroll = -1;
  1757. X    }
  1758. X
  1759. X/*
  1760. X *    lflush()                        Flush the output buffer
  1761. X *
  1762. X *    Returns nothing of value.
  1763. X *    for termcap version: Flush output in output buffer according to output
  1764. X *                         status as indicated by `enable_scroll'
  1765. X */
  1766. X#ifndef VT100
  1767. Xstatic int scrline=18; /* line # for wraparound instead of scrolling if no DL */
  1768. Xlflush ()
  1769. X    {
  1770. X    register int lpoint;
  1771. X    register char *str;
  1772. X    static int curx = 0;
  1773. X    static int cury = 0;
  1774. X
  1775. X    if ((lpoint = lpnt - lpbuf) > 0)
  1776. X        {
  1777. X#ifdef EXTRA
  1778. X        c[BYTESOUT] += lpoint;
  1779. X#endif
  1780. X        if (enable_scroll <= -1) {
  1781. X            flush_buf();
  1782. X# ifdef DGK_MSDOS
  1783. X            /* Catch write errors on save files
  1784. X             */
  1785. X                if (write(lfd,lpbuf,lpoint) != lpoint) {
  1786. X                    if (save_mode)
  1787. X                        longjmp(save_jbuf, -1);
  1788. X                    else
  1789. X                        warn("Error writing output file\n");
  1790. X                }
  1791. X# else
  1792. X                if (write(lfd,lpbuf,lpoint) != lpoint)
  1793. X                write(2,"error writing to output file\n",29);
  1794. X# endif
  1795. X            lpnt = lpbuf;    /* point back to beginning of buffer */
  1796. X            return;
  1797. X        }
  1798. X        for (str = lpbuf; str < lpnt; str++)
  1799. X            {
  1800. X            if (*str>=32)    { ttputch (*str); curx++; }
  1801. X            else switch (*str) {
  1802. X                case CLEAR:        tputs (CL, 0, ttputch);        curx = cury = 0;
  1803. X                                break;
  1804. X
  1805. X                case CL_LINE:    tputs (CE, 0, ttputch);
  1806. X                                break;
  1807. X
  1808. X                case CL_DOWN:    tputs (CD, 0, ttputch);
  1809. X                                break;
  1810. X
  1811. X                case ST_START:    tputs (SO, 0, ttputch);
  1812. X                                break;
  1813. X
  1814. X                case ST_END:    tputs (SE, 0, ttputch);
  1815. X                                break;
  1816. X
  1817. X                case CURSOR:    curx = *++str - 1;        cury = *++str - 1;
  1818. X                                tputs (tgoto (CM, curx, cury), 0, ttputch);
  1819. X                                break;
  1820. X
  1821. X                case '\n':        if ((cury == 23) && enable_scroll)
  1822. X                                  {
  1823. X                                  if (!DL || !AL) /* wraparound or scroll? */
  1824. X                                    {
  1825. X                                    if (++scrline > 23) scrline=19;
  1826. X
  1827. X                                    if (++scrline > 23) scrline=19;
  1828. X                                    tputs (tgoto (CM, 0, scrline), 0, ttputch);
  1829. X                                    tputs (CE, 0, ttputch);
  1830. X
  1831. X                                    if (--scrline < 19) scrline=23;
  1832. X                                    tputs (tgoto (CM, 0, scrline), 0, ttputch);
  1833. X                                    tputs (CE, 0, ttputch);
  1834. X                                    }
  1835. X                                  else
  1836. X                                    {
  1837. X                                    tputs (tgoto (CM, 0, 19), 0, ttputch);
  1838. X                                    tputs (DL, 0, ttputch);
  1839. X                                    tputs (tgoto (CM, 0, 23), 0, ttputch);
  1840. X                                /*    tputs (AL, 0, ttputch); */
  1841. X                                    }
  1842. X                                  }
  1843. X                                else
  1844. X                                  {
  1845. X                                  ttputch ('\n');        cury++;
  1846. X                                  }
  1847. X                                curx = 0;
  1848. X                                break;
  1849. X                case T_INIT:
  1850. X                    if (TI)
  1851. X                        tputs(TI, 0, ttputch);
  1852. X                    break;
  1853. X                case T_END:
  1854. X                    if (TE)
  1855. X                        tputs(TE, 0, ttputch);
  1856. X                    break;
  1857. X                default:
  1858. X                    ttputch (*str);
  1859. X                    curx++;
  1860. X                }
  1861. X            }
  1862. X        }
  1863. X    lpnt = lpbuf;
  1864. X    flush_buf();    /* flush real output buffer now */
  1865. X    }
  1866. X#else VT100
  1867. X/*
  1868. X *    lflush()                        flush the output buffer
  1869. X *
  1870. X *    Returns nothing of value.
  1871. X */
  1872. Xlflush()
  1873. X    {
  1874. X    register int lpoint;
  1875. X    if ((lpoint = lpnt - lpbuf) > 0)
  1876. X        {
  1877. X#ifdef EXTRA
  1878. X        c[BYTESOUT] += lpoint;
  1879. X#endif
  1880. X        if (write(lfd,lpbuf,lpoint) != lpoint)
  1881. X            write(2,"error writing to output file\n",29);
  1882. X        }
  1883. X    lpnt = lpbuf;    /* point back to beginning of buffer */
  1884. X    }
  1885. X#endif VT100
  1886. X
  1887. X#ifndef VT100
  1888. Xstatic int index=0;
  1889. X/*
  1890. X * ttputch(ch)        Print one character in decoded output buffer.
  1891. X */
  1892. Xstatic int ttputch(c)
  1893. Xint c;
  1894. X    {
  1895. X    outbuf[index++] = c;
  1896. X    if (index >= BUFBIG)  flush_buf();
  1897. X    }
  1898. X
  1899. X/*
  1900. X * flush_buf()            Flush buffer with decoded output.
  1901. X */
  1902. Xstatic flush_buf()
  1903. X    {
  1904. X    if (index) write(lfd, outbuf, index);
  1905. X    index = 0;
  1906. X    }
  1907. X
  1908. X/*
  1909. X *    char *tmcapcnv(sd,ss)  Routine to convert VT100 escapes to termcap format
  1910. X *
  1911. X *    Processes only the \33[#m sequence (converts . files for termcap use 
  1912. X */
  1913. Xchar *tmcapcnv(sd,ss)  
  1914. X    register char *sd,*ss;
  1915. X    {
  1916. X    register int tmstate=0;    /* 0=normal, 1=\33 2=[ 3=# */
  1917. X    char tmdigit=0;    /* the # in \33[#m */
  1918. X    while (*ss)
  1919. X        {
  1920. X        switch(tmstate)
  1921. X            {
  1922. X            case 0:    if (*ss=='\33')  { tmstate++; break; }
  1923. X              ign:  *sd++ = *ss;
  1924. X              ign2: tmstate = 0;
  1925. X                    break;
  1926. X            case 1: if (*ss!='[') goto ign;
  1927. X                    tmstate++;
  1928. X                    break;
  1929. X            case 2: if (isdigit(*ss)) { tmdigit= *ss-'0'; tmstate++; break; }
  1930. X                    if (*ss == 'm') { *sd++ = ST_END; goto ign2; }
  1931. X                    goto ign;
  1932. X            case 3: if (*ss == 'm')
  1933. X                        {
  1934. X                        if (tmdigit) *sd++ = ST_START;
  1935. X                            else *sd++ = ST_END;
  1936. X                        goto ign2;
  1937. X                        }
  1938. X            default: goto ign;
  1939. X            };
  1940. X        ss++;
  1941. X        }
  1942. X    *sd=0; /* NULL terminator */
  1943. X    return(sd);
  1944. X    }
  1945. X#endif VT100
  1946. X
  1947. X/*
  1948. X *    beep()        Routine to emit a beep if enabled (see no-beep in .larnopts)
  1949. X */
  1950. Xbeep() {
  1951. X    if (!nobeep) *lpnt++ = '\7';
  1952. X    }
  1953. END_OF_FILE
  1954. if test 25801 -ne `wc -c <'io.c'`; then
  1955.     echo shar: \"'io.c'\" unpacked with wrong size!
  1956. fi
  1957. # end of 'io.c'
  1958. fi
  1959. echo shar: End of archive 7 \(of 11\).
  1960. cp /dev/null ark7isdone
  1961. MISSING=""
  1962. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  1963.     if test ! -f ark${I}isdone ; then
  1964.     MISSING="${MISSING} ${I}"
  1965.     fi
  1966. done
  1967. if test "${MISSING}" = "" ; then
  1968.     echo You have unpacked all 11 archives.
  1969.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1970. else
  1971.     echo You still need to unpack the following archives:
  1972.     echo "        " ${MISSING}
  1973. fi
  1974. ##  End of shell archive.
  1975. exit 0
  1976.